package com.openstack4j.qx.imp;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


import org.openstack4j.api.OSClient.OSClientV2;
import org.openstack4j.api.compute.ComputeFloatingIPService;
import org.openstack4j.api.compute.ComputeService;
import org.openstack4j.api.compute.ServerService;
import org.openstack4j.model.common.ActionResponse;
import org.openstack4j.model.compute.FloatingIP;
import org.openstack4j.model.compute.Server;
import org.openstack4j.openstack.OSFactory;

import com.openstack4j.qx.IPController;
import com.openstack4j.qx.pojo.ApplyIPResp;
import com.openstack4j.qx.pojo.BaseResp;

/**
 * ClassName:IPcontrollerImpl
 * Function: IP相关操作接口方法具体实现. 
 * Reason:	   调用openstack底层操作方式实现.
 * Create Date:  2016年12月5日
 * Author:       yuanzhijin
 * @see 	 
 */

public class IPcontrollerImpl extends BaseControllerImp implements IPController {
	
	
	BaseResp baseResp = new BaseResp();
	
	
	/**
	 * @todo 定义参数与具体实现方式参数不匹配，需要商讨协定
	 *
	 */
	@Override
	public ApplyIPResp applyIp(String ipType, String appId, String appName) {
		
		OSClientV2 os = OSFactory.builderV2().endpoint("http://10.50.0.10:5000/v2.0")
				.credentials("admin", "ADMIN_PASS").tenantName("admin").authenticate();

		ComputeService  computeService =os.compute();
		
		ComputeFloatingIPService computeFloatingIpservice=computeService.floatingIps();
		
		//获取网络池
		List<String> poolNameList=computeFloatingIpservice.getPoolNames();
		
		FloatingIP floatingIp;
		
		ApplyIPResp ipResp =new ApplyIPResp();
		
		try {
			//在本环境中目前选定为Floating Ip作为基础池去申请开辟ip
			floatingIp=computeFloatingIpservice.allocateIP(poolNameList.get(2));
			ipResp.setIp(floatingIp.getFloatingIpAddress());
			
		} catch (Exception e) {
			ipResp.setFaultstring(e.getMessage());
		}
		return ipResp;
	}

	
	/**
	 * 释放ip 
	 * String ip:ip地址
	 * 通过传入ip地址为参数，释放该ip
	 */
	
	@Override
	public BaseResp releaseIp(String ip) {
		
		try {
			OSClientV2 os = OSFactory.builderV2().endpoint("http://10.50.0.10:5000/v2.0")
					.credentials("admin", "ADMIN_PASS").tenantName("admin").authenticate();
			
			ComputeService  computeService =os.compute();
			
			ComputeFloatingIPService computeFloatingIpservice=computeService.floatingIps();
			
			//列出所有floatingIP
			List<FloatingIP> floatingIpList =(List<FloatingIP>) computeFloatingIpservice.list();
			
			//存放floating的ip（键），id（值），通过floatingip查找其Id
			Map<String,String> floatingIpMap = new HashMap<String,String>();
			
			for (FloatingIP floatingIP : floatingIpList) {
				floatingIpMap.put( floatingIP.getFloatingIpAddress(),floatingIP.getId());
			}
		
			if(isFloatingIPExist(computeFloatingIpservice,ip)){
				ActionResponse actionResponse =computeFloatingIpservice.deallocateIP(floatingIpMap.get(ip));
				if(!actionResponse.isSuccess()){
					baseResp.setFaultstring(actionResponse.getFault());
				}
			}else{
				baseResp.setFaultstring("Floating Ip not found");
			}
			
		} catch (Exception e) {
			baseResp.setFaultstring(e.getMessage());
		}
		return baseResp;
	}

	/**
	 * 绑定ip 
	 * String ip:ip地址,String resourceId:虚机Id
	 * 通过传入ip地址为参数，释放该ip
	 */
	@Override
	public BaseResp bindIp(String ip, String resourceId) {
		
		try {
			
			OSClientV2 os = OSFactory.builderV2().endpoint("http://10.50.0.10:5000/v2.0")
					.credentials("admin", "ADMIN_PASS").tenantName("admin").authenticate();
			
			ComputeService  computeService =os.compute();
											
			ComputeFloatingIPService computeFloatingIpservice=computeService.floatingIps();
			
			ServerService service=computeService.servers();
			
			//判断ip是否存在
			if(!isFloatingIPExist(computeFloatingIpservice, ip)){
				baseResp.setFaultstring("ip is not found!");
			}else{
				Server bindServer =service.get(resourceId);
				//判断server是否存在
				if(bindServer!=null){
					ActionResponse actionResponse =computeFloatingIpservice.addFloatingIP(bindServer, ip);
					if(!actionResponse.isSuccess()){
						baseResp.setFaultstring(actionResponse.getFault());
					}
				}else{
					baseResp.setFaultstring("resourceId is not found!");
				}
			}
		
		}catch(Exception e){
			baseResp.setFaultstring(e.getMessage());
		}
		return baseResp;
	}

	
	/**
	 * 解绑ip 
	 * String ip:ip地址,String resourceId:虚机Id
	 * 通过传入ip地址为参数，解绑该ip与虚拟机的绑定
	 */
	@Override
	public BaseResp unbindIp(String ip, String resourceId) {
		
		try {
			
			OSClientV2 os = OSFactory.builderV2().endpoint("http://10.50.0.10:5000/v2.0")
					.credentials("admin", "ADMIN_PASS").tenantName("admin").authenticate();
			
			ComputeService  computeService =os.compute();
											
			ComputeFloatingIPService computeFloatingIpservice=computeService.floatingIps();
			
			ServerService service=computeService.servers();
			
			Server bindServer =service.get(resourceId);
			//判断server是否存在
			if(bindServer != null){
				//判断传入ip是否与该虚机绑定
				if(bindServer.getAccessIPv4().equals(ip)){
					ActionResponse actionResponse =computeFloatingIpservice.addFloatingIP(bindServer, ip);
					if(!actionResponse.isSuccess()){
						baseResp.setFaultstring(actionResponse.getFault());
					}
				}else{
					//ip 未与该虚机绑定
					baseResp.setFaultstring("ip is not binding with this resource!");
				}
			}else{
				baseResp.setFaultstring("resourceId is not found!");
			}
		}catch(Exception e){
			baseResp.setFaultstring(e.getMessage());
		}
		return baseResp;
	}
	
	
	/**
	 * 判断floatingip是否存在 
	 * List<FloatingIP>  floatingIpList:所有浮动ip
	 * String ipAddress ：欲判断ip
	 * return boolean
	 */
	private static boolean isFloatingIPExist(ComputeFloatingIPService computeFloatingIpservice,String ipAddress){
		//列出所有floatingIP
		List<FloatingIP> floatingIpList =(List<FloatingIP>) computeFloatingIpservice.list();
		
		//存放floating的ip（键），id（值），通过floatingip查找其Id
		Map<String,String> floatingIpMap = new HashMap<String,String>();
		
		for (FloatingIP floatingIP : floatingIpList) {
			floatingIpMap.put( floatingIP.getFloatingIpAddress(),floatingIP.getId());
		}
		return floatingIpMap.containsKey(ipAddress);
	}
	
	
}

